#include "stdafx.h"
#include "label.h"

namespace gtl
{

namespace skins
{

label::label()
{
	m_hand = NULL;
	m_font = NULL;
	m_fmt_flags = 0;
	m_text_clr = RGB(0, 0, 0);
}

label::~label()
{
	destroy();
}

BEGIN_MESSAGE_MAP(label, wnd)
	ON_WM_SETCURSOR()
	ON_WM_LBUTTONUP()
	ON_WM_ERASEBKGND()
END_MESSAGE_MAP()

unsigned int label::initialize(gtl::xml& node, wnd* parent_wnd)
{
	pane::initialize(node, parent_wnd);

	int x = node(_T("x"), true);
	int y = node(_T("y"), true);
	int width = node(_T("width"), true);
	int height = node(_T("height"), true);
	m_adapt = node(_T("adapt"), true);
	m_text_clr = node(_T("color"), true);
	m_action = node(_T("action"), true);
	m_hypelink = node(_T("hypelink"), true);
	gtl::tstr font = node(_T("font"), true);
	m_font = get_font(font);

	if(!m_hypelink.empty() || !m_action.empty())
		m_hand = ::LoadCursor(NULL, IDC_HAND);

	gtl::tstr flags = node(_T("align"), true);
	std::vector<gtl::tstr> vecFlags;
	flags.split(vecFlags, _T(","));
	for(size_t i = 0; i < vecFlags.size(); ++i)
	{
		if(vecFlags[i].icmp(_T("left")))
			m_fmt_flags |= DT_LEFT;
		else if(vecFlags[i].icmp(_T("right")))
			m_fmt_flags |= DT_RIGHT;
		else if(vecFlags[i].icmp(_T("top")))
			m_fmt_flags |= DT_TOP;
		else if(vecFlags[i].icmp(_T("bottom")))
			m_fmt_flags |= DT_BOTTOM;
		else if(vecFlags[i].icmp(_T("center")))
			m_fmt_flags |= DT_CENTER;
		else if(vecFlags[i].icmp(_T("vcenter")))
			m_fmt_flags |= DT_VCENTER;
		else if(vecFlags[i].icmp(_T("singleline")))
			m_fmt_flags |= DT_SINGLELINE;
	}

	if(!(m_fmt_flags & DT_SINGLELINE))
		m_fmt_flags |= DT_WORDBREAK;

	DWORD dwStyle = node(_T("style"), true);
	gtl::tstr text = node(_T("text"), true);
	CRect rect(x, y, x + width, y + height);
	Create(NULL, NULL, WS_VISIBLE | dwStyle, rect, parent_wnd, 0);
	SetWindowText(text);

	CClientDC dc(this);
	CFont* pOldFont = NULL;
	if(m_font != NULL)
		dc.SelectObject(m_font);
	if(m_fmt_flags & DT_WORDBREAK)
	{
		std::vector<gtl::tstr> subtexts;
		text.split(subtexts, _T("\n"));
		size_t index = 0;
		size_t length = 0;
		for(size_t i = 0; i < subtexts.size(); ++i)
		{
			size_t len = subtexts[i].length();
			if(len > length)
			{
				index = i;
				length = len;
			}
		}

		if(!subtexts.empty())
		{
			CSize size = dc.GetTextExtent(subtexts[index].c_str());
			if(size.cx > 0)
			{
				rect.right = rect.left + size.cx;
				MoveWindow(rect);
			}
		}
	}
	else
	{
		CSize size = dc.GetTextExtent(text.c_str());
		if(size.cx > 0)
		{
			rect.right = rect.left + size.cx;
			MoveWindow(rect);
		}
	}

	return reinterpret_cast<unsigned int>(m_hWnd);
}

BOOL label::OnEraseBkgnd(CDC* pDC)
{
	CString strText;
	GetWindowText(strText);
	strText.Replace(_T("\\n"), _T("\n"));

	CRect rcClient;
	GetClientRect(rcClient);

	pDC->SetBkMode(TRANSPARENT);
	pDC->SetTextColor(m_text_clr);
	CFont* pFont = pDC->SelectObject(m_font);
	pDC->DrawText(strText, rcClient, m_fmt_flags);
	pDC->SelectObject(pFont);

	return TRUE;
}

BOOL label::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message)
{
	if(m_hand != NULL)
	{
		::SetCursor(m_hand);
		return TRUE;
	}

	return CWnd::OnSetCursor(pWnd, nHitTest, message);
}

void label::OnLButtonUp(UINT nFlags, CPoint point)
{
	if(m_hand != NULL)
	{
		if(!m_action.empty())
		{
			output(this, m_action, NULL, NULL);
		}
		else if(!m_hypelink.empty())
		{
			ShellExecute(NULL, _T("open"), m_hypelink, NULL, NULL, SW_SHOW);
		}
	}

	CWnd::OnLButtonUp(nFlags, point);
}

} // end of namespace skins

} // end of namespace gtl
